package d4_collection_travesal;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

public class CollectionTest {
    public static void main(String[] args) {
        // 目标：三种遍历可能出现的并发修改异常问题。
        Collection<String> list = new ArrayList<>();
        list.add("Java入门");
        list.add("宁夏枸杞");
        list.add("黑枸杞");
        list.add("人字拖");
        list.add("特技枸杞");
        list.add("枸杞子");

        //1、使用迭代器遍历集合并删除枸杞
        // 注意1: 如果使用迭代器遍历, 并用集合删除集合, 并出现并发修改异常, 程序出bug。 ConcurrentModificationException
        Iterator<String> it = list.iterator();
        while (it.hasNext()) {
            String info = it.next();
            if (info.contains("枸杞")) {
                //list.remove(info);//如果使用迭代器遍历, 并用集合删除数据, 程序就会报并发修改异常 ConcurrentModificationException
                it.remove();     //解决方案: 必须调用迭代器自己的方法进行删除操作, 才不会出现bug
                //其实底层做了i--  所以迭代器才能删除成功

            }
        }
        System.out.println(list);

        //2、使用增强for进行遍历集合并删除枸杞 (本质就是迭代器): 必须报错, 无法解决
        // 底层本质就是使用迭代器--->但是无法拿到迭代器对象
        //增强for本质就是迭代器iterator -->但是无法拿到迭代器 无法进行删除操作
        Collection<String> list2 = new ArrayList<>();
        list2.add("Java入门");
        list2.add("宁夏枸杞");
        list2.add("黑枸杞");
        list2.add("人字拖");
        list2.add("特技枸杞");
        list2.add("枸杞子");
        /*for (String name : list2) {
            if (name.contains("枸杞")){
                list2.remove(name);
            }
        }
        //进行集合输出
        System.out.println(list2);*/

        //3、Lambda进行遍历集合,并删除包含枸杞(本质是增强for循环,) : 必须报错, 无法解决
        ArrayList<String> list3 = new ArrayList<>();
        list3.add("Java入门");
        list3.add("宁夏枸杞");
        list3.add("黑枸杞");
        list3.add("人字拖");
        list3.add("特技枸杞");
        list3.add("枸杞子");
        list3.forEach(name -> {
            if (name.contains("枸杞")){
                list3.remove(name);
            }
        });
        /*if (modCount != expectedModCount)
            throw new ConcurrentModificationException();
            还是进行判断,修改就抛异常
        * */

        //注意: 如果是ArrayList带索引的集合, 我们可以用for循环进行删除每次退一步, 或者从后面倒着遍历删除
    }
}
